package com.atguigu.day4;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/*
 * 写线程首先获取写锁，更新数据，然后将锁降级为读锁，读线程在获取读锁后读取数据。
 * 这个过程演示了锁降级的概念，允许多个线程在持有读锁的情况下同时访问数据
 *提高了并发性能
 * 请注意，在锁降级期间，我们要确保数据的一致性。即在降级为读锁之前和之后都可以正确读取数据
 *这是锁降级的关键部分（先获取读锁，再释放写锁）
 *
 * */
public class LockDowngradingDemo {


    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private final Lock readLock = readWriteLock.readLock();
    private final Lock writeLock = readWriteLock.writeLock();
    private int data = 0;

    public int readData() {
        readLock.lock();
        try {
            return data;
        } finally {
            readLock.unlock();
        }
    }

    public void updateData(int newData) {
        writeLock.lock();
        try {
            data = newData;
            System.out.println("数据更新为：" + data);
            //锁降级(先获取读锁，再释放写锁)
            readLock.lock();
            System.out.println("Lock Downgrading to readLock");
        } finally {
            writeLock.unlock();
        }


        //在持有读锁的情况下读己之所写
        try {
            int currentData = readData();
            System.out.println("Read currentData: " + currentData);
        } finally {
            readLock.unlock();
        }
    }

    public static void main(String[] args) {
        LockDowngradingDemo lockDowngradingDemo = new LockDowngradingDemo();
        new Thread(() -> {
            lockDowngradingDemo.updateData(1024);
        }, "T1").start();
        new Thread(() -> {
            lockDowngradingDemo.updateData(620);
        }, "T2").start();


        new Thread(() -> {
            int currentData = lockDowngradingDemo.readData();
            System.out.println("Reader got data " + currentData);
        }, "T3").start();

    }
}
